package com.glqiang.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.glqiang.domain.entity.Menu;
import com.glqiang.domain.vo.MenuVo;
import com.glqiang.mapper.MenuMapper;
import com.glqiang.response.ResponseResult;
import com.glqiang.service.MenuService;
import com.glqiang.util.BeanCopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * (Menu)表服务实现类
 *
 * @author glqiang
 * @since 2022-11-22 22:36:00
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Override
    public ResponseResult<List<MenuVo>> listMenu(Long userId) {
        List<Menu> childrenMenus = menuMapper.selectMenusByUserId(userId);
        // 获取父菜单
        List<Menu> parentMenus = childrenMenus.stream()
                .filter(menu -> menu.getParentId() != 0)
                .map(menu -> getById(menu.getParentId()))
                .distinct()
                .collect(Collectors.toList());
        List<Menu> menus = Stream.of(parentMenus.stream(), childrenMenus.stream())
                .flatMap(Function.identity())
                .sorted(Comparator.comparing(Menu::getParentId))
                .sorted(Comparator.comparing(Menu::getSortId))
                .collect(Collectors.toList());
        List<MenuVo> menuVos = builderMenuTree(menus);
        return ResponseResult.success(menuVos);
    }

    private List<MenuVo> builderMenuTree(List<Menu> menus) {
        List<MenuVo> menuVos = BeanCopyUtils.copyBeanList(menus, MenuVo.class);
        return menuVos.stream()
                // 先找出第一层菜单，再找他们的子菜单设置到children中
                .filter(menuVo -> menuVo.getParentId() == 0)
                .map(menuVo -> menuVo.setChildren(getChildren(menuVo, menuVos)))
                .collect(Collectors.toList());
    }

    /**
     * 获取传入参数的子Menu集合
     *
     * @param menuVo  顶级菜单
     * @param menuVos 菜单列表
     * @return 设置了子菜单的菜单列表
     */
    private List<MenuVo> getChildren(MenuVo menuVo, List<MenuVo> menuVos) {
        return menuVos.stream()
                .filter(m -> m.getParentId().equals(menuVo.getId()))
                .collect(Collectors.toList());
    }
}

